package br.edu.ufcg.lsd.wbis.control.equipment;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.sql.Date;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Test;

import br.edu.ufcg.lsd.wbis.DatabaseTestCase;
import br.edu.ufcg.lsd.wbis.control.exception.CannotOpenDatabaseSessionException;
import br.edu.ufcg.lsd.wbis.control.exception.DuplicatedIdentifierException;
import br.edu.ufcg.lsd.wbis.control.exception.UnknownEntityException;
import br.edu.ufcg.lsd.wbis.control.user.User;
import br.edu.ufcg.lsd.wbis.control.user.UserLevel;
import br.edu.ufcg.lsd.wbis.control.user.UserManager;
import br.edu.ufcg.lsd.wbis.control.util.HibernateUtil;

public class EquipmentManagerTest extends DatabaseTestCase {

	private final EquipmentDAO daoMock = EasyMock
			.createMock(EquipmentDAO.class);
	private EquipmentManager manager;

	public void setup() {
		manager = new EquipmentManager(daoMock);
	}

	@After
	public void tearDown() throws Exception {
		EasyMock.reset(daoMock);
		manager = null;
		rebuild();
	}

	/**
	 * DOne
	 * 
	 * @throws DuplicatedIdentifierException
	 * @throws UnknownEntityException
	 */
	@Test
	public void testAddEquipment() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);
		userManager.addUser("john2", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john2");
		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		Keyboard keyboard = new Keyboard("K1", "HP", "8347JFF7S", new Date(
				1234567890), "a201", "Serra Limpa", new byte[100], desktop,
				true, "ABNT2");

		Mouse mouse = new Mouse("M1", "Microsoft", "SD7SFD00", new Date(
				1234567890), "White", "Serra L impa", new byte[100], desktop,
				true, true);

		Display monitor = new Display("MO2", "Samsung", "AJ37856", new Date(
				1234567890), "932B Plus", "Serra Limpa", new byte[100],
				desktop, true, false, "LCD", "19\" Wide");

		DiscDriver discDriver = new DiscDriver("D1", "Maxtor", "M837A-AS",
				getDate(), "A3a", "Rainha", new byte[100], desktop, true,
				false, false, true, "CD-RW/DVD-RW/Lightscribe");

		HardDisk hardDisk = new HardDisk("H1", "Samsung", "MX-8493-C",
				getDate(), "Modelo Tal", "Rainha", new byte[100], desktop,
				false, false, false, "Hd de backup", 250, "SATA");

		Memory memory = new Memory("M0387", "Kingston", "k487", getDate(),
				"Sei la", "Rainha", new byte[100], desktop, true, 2, 400,
				"DDR2");

		NoBreak noBreak = new NoBreak("3", "MAB", "MAS093", getDate(),
				"MODEL-A", "Rainha", new byte[100], true, 3);

		PowerSource powerSource = new PowerSource("4", "HP", "HP-37a",
				getDate(), "ATX", "Rainha", new byte[100], desktop, true, 550);

		Printer printer = new Printer("10", "HP", "h47", getDate(), "h47",
				"Corredor Terreo", new byte[100], true, false);

		Processor processor = new Processor("11", "Intel", "HT-20598",
				getDate(), "Intel Code 2 Duo HT", "Rainha", new byte[100],
				null, true, "2.5Ghz", "4Mb", 2);

		Router router = new Router("12", "CISCO", "09385", getDate(), "ATQ-02",
				"Serra Limpa", new byte[100], true, RouterType.SWITCH_NETWORK,
				"Sei la", 32);

		VideoCard videoCard = new VideoCard("13", "GeFOrce", "GF-1398",
				getDate(), "FX5500", "Serra Limpa", new byte[100], desktop,
				true, 256, 400, "PCI-Express");

		
		
		myManager.addDisplay("1", "Samsung", "AJ37856", new Date(1234567890),
				"932B Plus", "Serra Limpa", new byte[100],  true,
				false, "LCD", "19\" Wide");
		myManager.addDiscDriver("2", "Maxtor", "M837A-AS", getDate(), "A3a",
				"Rainha", new byte[100],  true, false, false, true,
				"CD-RW/DVD-RW/Lightscribe");
		myManager.addHardDisk("3", "Samsung", "MX-8493-C", getDate(),
				"Modelo Tal", "Rainha", new byte[100],  false, false,
				false, "Hd de backup", 250, "SATA");
		myManager.addKeyboard("4", "HP", "8347JFF7S", new Date(1234567890),
				"a201", "Serra Limpa", new byte[100],  true, "ABNT2");
		myManager.addMemory("5", "Kingston", "k487", getDate(), "Sei la",
				"Rainha", new byte[100],  true, 2, 400, "DDR2");
		myManager.addMouse("6", "Microsoft", "SD7SFD00", new Date(1234567890),
				"White", "Serra L impa", new byte[100],  true, true);
		myManager.addNoBreak("7", "MAB", "MAS093", getDate(), "MODEL-A",
				"Rainha", new byte[100], true, 3);
		myManager.addPowerSource("8", "HP", "HP-37a", getDate(), "ATX",
				"Rainha", new byte[100],  true, 550);
		myManager.addPrinter("9", "HP", "h47", getDate(), "h47",
				"Corredor Terreo", new byte[100], true, false);
		myManager.addProcessor("10", "Intel", "HT-20598", getDate(),
				"Intel Code 2 Duo HT", "Rainha", new byte[100],  true,
				"2.5Ghz", "4Mb", 2);
		myManager.addRouter("11", "CISCO", "09385", getDate(), "ATQ-02",
				"Serra Limpa", new byte[100], true, RouterType.SWITCH_NETWORK,
				"Sei la", 32);
		myManager.addVideoCard("12", "GeFOrce", "GF-1398", getDate(), "FX5500",
				"Serra Limpa", new byte[100],  true, 256, 400,
				"PCI-Express");

		assertEquals(1, myManager.getKeyboards().size());
		assertEquals(1, myManager.getMouses().size());
		assertEquals(1, myManager.getDisplays().size());
		assertEquals(1, myManager.getDiscDrivers().size());
		assertEquals(1, myManager.getHardDisks().size());
		assertEquals(1, myManager.getMemories().size());
		assertEquals(1, myManager.getNoBreaks().size());
		assertEquals(1, myManager.getPowerSources().size());
		assertEquals(1, myManager.getPrinters().size());
		assertEquals(1, myManager.getProcessors().size());
		assertEquals(1, myManager.getRouters().size());
		assertEquals(1, myManager.getVideoCards().size());
		
		
		
	}

	 @Test
	public void testComponentOnComputer() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);
		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");
		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);

		DiscDriver discDriver = new DiscDriver("D1", "Maxtor", "M837A-AS",
				getDate(), "A3a", "Rainha", new byte[100], null, true, false,
				false, true, "CD-RW/DVD-RW/Lightscribe");

		myManager.addDiscDriver("D1", "Maxtor", "M837A-AS", getDate(), "A3a",
				"Rainha", new byte[100], true, false, false, true,
				"CD-RW/DVD-RW/Lightscribe");

		assertEquals(myManager.getDiscDrivers().size(), 1);

		assertEquals(myManager.getDiscDriver("D1").getInventoryCode(),
				discDriver.getInventoryCode());

		discDriver.setComputer(desktop);
		DiscDriver discDriver2 = myManager.getDiscDriver("D1");

		assertEquals(discDriver.getInventoryCode(), discDriver2
				.getInventoryCode());
		myManager.addComponentToComputer("AJK-333", "D1");

		assertEquals(myManager.getComputer("AJK-333").getComponents().size(), 1);

//		assertTrue(myManager.getOtherEquipment("D1").equals(discDriver));

		// Should not return null!!
//		assertEquals(myManager.getDiscDriver("D1").getComputer()
//				.getInventoryCode(), "AJK-333");
	}

	/**
	 * 
	 * @throws DuplicatedIdentifierException
	 * @throws UnknownEntityException
	 */
	 @Test
	public void testUpdateComputer() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);
		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");
		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);

		desktop.setComputerType(ComputerType.SERVER);
		desktop.setLocalization("Serra Limpa");

		myManager.updateComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "Serra Limpa", null, false, true, ComputerType.SERVER,
				john, 1, 1);

		assertTrue(myManager.getComputer("AJK-333").equals(desktop));
		assertEquals(myManager.getComputers().size(), 1);
	}

	/**
	 * 
	 * @throws DuplicatedIdentifierException
	 * @throws UnknownEntityException
	 */
	 @Test
	public void testOnDeleteUser() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);
		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");
		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);

		userManager.removeUser("john");
		Computer thatDesktop = myManager.getComputer("AJK-333");
		assertEquals(thatDesktop.getOwner(), null);

	}

	/**
	 * 
	 * @throws DuplicatedIdentifierException
	 * @throws UnknownEntityException
	 */
	 @Test
	public void testOnDeleteComputer() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);

		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");

		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);

		assertEquals(myManager.getComputers().size(), 1);

		myManager.removeEquipment("AJK-333");
		assertEquals(myManager.getComputers().size(), 0);
	}

	// 855 de EquipmentManager
	 @Test
	public void testOnDeleteComponents() throws DuplicatedIdentifierException,
			UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);

		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");

		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);

		Keyboard keyboard = new Keyboard("K1", "HP", "8347JFF7S", new Date(
				1234567890), "a201", "Serra Limpa", new byte[100], desktop,
				true, "ABNT2");

		Mouse mouse = new Mouse("M1", "Microsoft", "SD7SFD00", new Date(
				1234567890), "White", "Serra Limpa", new byte[100], desktop,
				true, true);

		Display monitor = new Display("MO2", "Samsung", "AJ37856", new Date(
				1234567890), "932B Plus", "Serra Limpa", new byte[100],
				desktop, true, false, "LCD", "19\" Wide");

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);
		myManager.addKeyboard("K1", "HP", "8347JFF7S", new Date(1234567890),
				"a201", "Serra Limpa", new byte[100], true, "ABNT2");
		myManager.addMouse("M1", "Microsoft", "SD7SFD00", new Date(1234567890),
				"White", "Serra Limpa", new byte[100], true, true);
		myManager.addDisplay("MO2", "Samsung", "AJ37856", new Date(1234567890),
				"932B Plus", "Serra Limpa", new byte[100], true, false, "LCD",
				"19\" Wide");

		assertEquals(1, myManager.getComputers().size());
		assertEquals(1, myManager.getKeyboards().size());
		assertEquals(1, myManager.getMouses().size());
		assertEquals(1, myManager.getDisplays().size());

		myManager.addComponentToComputer("AJK-333", "K1");
		myManager.addComponentToComputer("AJK-333", "M1");
		myManager.addComponentToComputer("AJK-333", "MO2");

		assertEquals(3, myManager.getComputer("AJK-333").getComponents().size());

		myManager.removeComponentFromComputer("AJK-333", "K1");
		myManager.removeComponentFromComputer("AJK-333", "M1");
		myManager.removeComponentFromComputer("AJK-333", "MO2");

		assertEquals(0, myManager.getComputer("AJK-333").getComponents().size());
		assertEquals(1, myManager.getKeyboards().size());
		assertEquals(1, myManager.getMouses().size());
		assertEquals(1, myManager.getDisplays().size());

//		myManager.removeEquipment("K1");
//		myManager.removeEquipment("M1");
//		myManager.removeEquipment("MO2");
//
//		assertEquals(0, myManager.getComputer("AJK-333").getComponents().size());
//
//		assertEquals(1, myManager.getComputers().size());
//		assertEquals(0, myManager.getDisplays().size());
//		assertEquals(0, myManager.getMouses().size());
//		assertEquals(0, myManager.getKeyboards().size());
	}

	/**
	 * 
	 * @throws DuplicatedIdentifierException
	 * @throws UnknownEntityException
	 */
	 @Test
	public void testOnDeleteComputerWithComponents()
			throws DuplicatedIdentifierException, UnknownEntityException {
		rebuild();
		EquipmentManager myManager = new EquipmentManager();
		UserManager userManager = new UserManager();

		userManager.addListener(myManager);

		userManager.addUser("john", "johnpass", "john", "john@gmail.com", true,
				UserLevel.COMMON_USER);

		User john = userManager.getUser("john");

		Computer desktop = new Computer("AJK-333", "Toshiba", "aaa8333",
				getDate(), "AK-77", "marcelo", null, false, true,
				ComputerType.CLIENT, john, 1, 1);
		Keyboard keyboard = new Keyboard("K1", "HP", "8347JFF7S", new Date(
				1234567890), "a201", "Serra Limpa", new byte[100], desktop,
				true, "ABNT2");
		Mouse mouse = new Mouse("M1", "Microsoft", "SD7SFD00", new Date(
				1234567890), "White", "Serra Limpa", new byte[100], desktop,
				true, true);
		Display monitor = new Display("MO2", "Samsung", "AJ37856", new Date(
				1234567890), "932B Plus", "Serra Limpa", new byte[100],
				desktop, true, false, "LCD", "19\" Wide");

		myManager.addComputer("AJK-333", "Toshiba", "aaa8333", getDate(),
				"AK-77", "marcelo", null, false, true, ComputerType.CLIENT,
				john, 1, 1);
		myManager.addKeyboard("K1", "HP", "8347JFF7S", new Date(1234567890),
				"a201", "Serra Limpa", new byte[100], true, "ABNT2");
		myManager.addMouse("M1", "Microsoft", "SD7SFD00", new Date(1234567890),
				"White", "Serra Limpa", new byte[100], true, true);
		myManager.addDisplay("MO2", "Samsung", "AJ37856", new Date(1234567890),
				"932B Plus", "Serra Limpa", new byte[100], true, false, "LCD",
				"19\" Wide");

		assertEquals(1, myManager.getComputers().size());
		assertEquals(1, myManager.getKeyboards().size());
		assertEquals(1, myManager.getMouses().size());
		assertEquals(1, myManager.getDisplays().size());

		myManager.addComponentToComputer("AJK-333", "K1");
		myManager.addComponentToComputer("AJK-333", "M1");
		myManager.addComponentToComputer("AJK-333", "K1");
		myManager.addComponentToComputer("AJK-333", "MO2");

		assertEquals(3, myManager.getComputer("AJK-333").getComponents().size());

		myManager.removeEquipment("AJK-333");

		assertEquals(1, myManager.getDisplays().size());
		assertEquals(1, myManager.getMouses().size());
		assertEquals(1, myManager.getKeyboards().size());
	}

	private void rebuild() throws CannotOpenDatabaseSessionException {
		HibernateUtil.getInstance(HibernateUtil.getTestingConfigFilePath());
	}
}
